/*
Copyright (C) 2007 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// @fileoverview Main class for the gadget - handles GD events

var tatwGadget = new TatwGadget();

// TODO: Use closures on event handlers to remove global scope.

/**
 * Main class of the main view to handle all UI and functional stuff
 */
function TatwGadget() {
  this.menus = new Menus();
  this.clockPanel = null; // holds a reference to a panel of clocks
  this.shrinkTimer = null;

  // Check if a newer version has been installed
  var curVersion = parseInt(options.getValue(OPTION_NAMES.VERSION_NUM));
  if (isNaN(curVersion) || curVersion < VERSION) {
    options.removeAll();
    debug.trace('New version of gadget installed...');
    options.putValue(OPTION_NAMES.VERSION_NUM, VERSION);
  }
  plugin.onAddCustomMenuItems = this.menus.onAddCustomMenuItems;
}

/**
 * Called when the main view is opened
 * it sets default options and declares a new ClockPanel object
 */
TatwGadget.prototype.initiatePlugin = function() {
  // set the Options dialog to open normaly (not in add mode)
  options.putValue(OPTION_NAMES.OPTIONS_DIALOG_TYPE, 'NORMAL');
  // set other Options comunicators between options.js and main.js to none
  options.putValue(OPTION_NAMES.NEW_LOCATION, 'none');
  options.putValue(OPTION_NAMES.NEW_OFFSET, 'none');
  // set the default design
  options.putDefaultValue(OPTION_NAMES.DESIGN, 3);
  options.putDefaultValue(OPTION_NAMES.BACKGROUND, 1);
  // set the default to not show the seconds' handle
  options.putDefaultValue(OPTION_NAMES.SHOW_SECONDS, 0);
  // set the default to not show the time tooltip
  options.putDefaultValue(OPTION_NAMES.SHOW_TOOLTIP, 0);
  // set the default to shrink the clock when idle
  options.putDefaultValue(OPTION_NAMES.SHRINK_IF_IDLE, 1);
  // set deafault shrink time to 10 seconds
  options.putDefaultValue(OPTION_NAMES.SHRINK_TIME, 10);
  // set deafault shrink percent to 50%
  options.putDefaultValue(OPTION_NAMES.SHRINK_PERCENT, 50);
  // if there are no set options for the clocks add 3 clock with
  // London (GMT), San Francisco and local to the registry.
  var defaults = [{location: 'San Francisco', offsetMinutes: -480},
      {location: 'London', offsetMinutes: 0}];
  if (!options.exists(OPTION_NAMES.NUMBERED_PREFIX + 0 +
        OPTION_NAMES.NUMBERED_OFFSET)) {
    var now = new Date();
    now.setMonth(0);  // avoid getting daylight timezones
    var offset = now.getHours() * 60 + now.getMinutes() -
        now.getUTCHours() * 60 - now.getUTCMinutes();
    if (offset < -HALF_A_DAY) {
      offset += 2 * HALF_A_DAY;
    }
    if (offset > HALF_A_DAY) {
      offset -= 2 * HALF_A_DAY;
    }
    defaults.push({location: 'Local', offsetMinutes: offset});
    defaults.sort(ClockPanel.sortByOffset);
    for (var i = 0; i < defaults.length; ++i) {
      options.putValue(OPTION_NAMES.NUMBERED_PREFIX + i +
          OPTION_NAMES.NUMBERED_OFFSET, defaults[i].offsetMinutes);
      options.putValue(OPTION_NAMES.NUMBERED_PREFIX + i +
          OPTION_NAMES.NUMBERED_DESIGN, 3);
      options.putValue(OPTION_NAMES.NUMBERED_PREFIX + i +
          OPTION_NAMES.NUMBERED_BACKGROUND, 1);
      options.putValue(OPTION_NAMES.NUMBERED_PREFIX + i +
          OPTION_NAMES.NUMBERED_LOCATION, defaults[i].location);
    }
  }
  options.putDefaultValue(OPTION_NAMES.TOTAL_CLOCKS, defaults.length);
  // set the default clock arrangement to 2 line horizontal
  options.putDefaultValue(OPTION_NAMES.CLOCK_ARRANGEMENT, 2);
  this.clockPanel = new ClockPanel();
  this.clockPanel.toggleSecondsHandles(this.clockPanel.showSeconds);
  this.clockPanel.onMinuteTimer();
  view.onoptionchanged = this.onOptionChanged;
};

/**
 * Called when an option changes it's value
 * used to comunicate between the main view and the different options dialogs
 */
TatwGadget.prototype.onOptionChanged = function() {
  if (event.propertyName == OPTION_NAMES.CLOCK_ARRANGEMENT) {
    if (isNaN(parseInt(tatwGadget.clockPanel.clockArrangement =
        options.getValue(OPTION_NAMES.CLOCK_ARRANGEMENT)))) {
      options.putValue(OPTION_NAMES.CLOCK_ARRANGEMENT, 2);
      tatwGadget.clockPanel.clockArrangement = 2;
    }
    tatwGadget.clockPanel.arrangeClocks();
  } else if (event.propertyName == OPTION_NAMES.SHOW_SECONDS) {
    if (isNaN(parseInt(tatwGadget.clockPanel.showSeconds =
        options.getValue(OPTION_NAMES.SHOW_SECONDS)))) {
      options.putValue(OPTION_NAMES.SHOW_SECONDS, 0);
      tatwGadget.clockPanel.showSeconds = 0;
    }
    tatwGadget.clockPanel.showSeconds = tatwGadget.clockPanel.showSeconds == 1;
    tatwGadget.clockPanel.toggleSecondsHandles(
        tatwGadget.clockPanel.showSeconds);
  } else if (event.propertyName == OPTION_NAMES.SHOW_TOOLTIP) {
    if (isNaN(parseInt(tatwGadget.clockPanel.showTooltip =
        options.getValue(OPTION_NAMES.SHOW_TOOLTIP)))) {
      options.putValue(OPTION_NAMES.SHOW_TOOLTIP, 0);
      tatwGadget.clockPanel.showTooltip = 0;
    }
    tatwGadget.clockPanel.showTooltip = tatwGadget.clockPanel.showTooltip == 1;
    if (tatwGadget.clockPanel.showTooltip) {
      clearInterval(tatwGadget.clockPanel.minuteTimeout);
      tatwGadget.clockPanel.onMinuteTimer();
    } else {
      tatwGadget.clockPanel.hideTooltips();
    }
  } else if (event.propertyName == OPTION_NAMES.NEW_OFFSET) {
    var offset;
    var designId;
    var backgroundId;
    if (isNaN(parseInt(offset = options.getValue(OPTION_NAMES.NEW_OFFSET)))) {
      return;
    }
    if (isNaN(parseInt(designId = options.getValue(OPTION_NAMES.DESIGN)))) {
      designId = 0;
    }
    if (isNaN(parseInt(backgroundId =
        options.getValue(OPTION_NAMES.BACKGROUND)))) {
      backgroundId = 0;
    }
    if (designId < 0 || designId >
        CLOCK_INF.DESIGNS.length - 1) {
      designId = 0;
    }
    if (backgroundId < 0 || backgroundId >
        CLOCK_INF.BACKGROUND_NAMES.length - 1) {
      backgroundId = 0;
    }
    var locationName = options.getValue(OPTION_NAMES.NEW_LOCATION);
    var deleteNum = parseInt(options.getValue(OPTION_NAMES.EDIT_CLOCK_NUM));

    if (!isNaN(deleteNum) && deleteNum > -1) {
      tatwGadget.clockPanel.clocks[deleteNum].offsetMinutes = offset;
      tatwGadget.clockPanel.clocks[deleteNum].designId = designId;
      tatwGadget.clockPanel.clocks[deleteNum].backgroundId = backgroundId;
      tatwGadget.clockPanel.clocks[deleteNum].cityLabel.innerText =
          locationName;
    } else {
      tatwGadget.clockPanel.clocks.push(new Clock(view, designId, backgroundId,
          offset, locationName, false, true));
    }

    options.putValue(OPTION_NAMES.EDIT_CLOCK_NUM, -1);
    tatwGadget.clockPanel.clocks.sort(ClockPanel.sortByOffset);

    for (var i = 0; i < tatwGadget.clockPanel.clocks.length; ++i) {
      options.putValue(OPTION_NAMES.NUMBERED_PREFIX + i +
          OPTION_NAMES.NUMBERED_OFFSET,
          tatwGadget.clockPanel.clocks[i].offsetMinutes);
      options.putValue(OPTION_NAMES.NUMBERED_PREFIX + i +
          OPTION_NAMES.NUMBERED_DESIGN,
          tatwGadget.clockPanel.clocks[i].designId);
      options.putValue(OPTION_NAMES.NUMBERED_PREFIX + i +
          OPTION_NAMES.NUMBERED_BACKGROUND,
          tatwGadget.clockPanel.clocks[i].backgroundId);
      options.putValue(OPTION_NAMES.NUMBERED_PREFIX + i +
          OPTION_NAMES.NUMBERED_LOCATION,
          tatwGadget.clockPanel.clocks[i].cityLabel.innerText);
    }

    if (tatwGadget.clockPanel.minuteTimeout) {
      clearInterval(tatwGadget.clockPanel.minuteTimeout);
    }
    if (tatwGadget.clockPanel.secondInterval) {
      clearInterval(tatwGadget.clockPanel.secondInterval);
    }
    if (tatwGadget.clockPanel.zoomTimer) {
      clearInterval(tatwGadget.clockPanel.zoomTimer);
    }
    view.removeAllElements();
    tatwGadget.clockPanel = new ClockPanel();
    options.putValue(OPTION_NAMES.NEW_LOCATION, 'none');
    options.putValue(OPTION_NAMES.NEW_OFFSET, 'none');
    tatwGadget.onMouseOver();
    tatwGadget.onMouseOut();
    tatwGadget.clockPanel.toggleSecondsHandles(
        tatwGadget.clockPanel.showSeconds);
    tatwGadget.clockPanel.onMinuteTimer();
  } else if (event.propertyName == OPTION_NAMES.SHRINK_IF_IDLE) {
    if (isNaN(parseInt(tatwGadget.clockPanel.shrinkIfIdle =
        options.getValue(OPTION_NAMES.SHRINK_IF_IDLE)))) {
      options.putValue(OPTION_NAMES.SHRINK_IF_IDLE, 1);
      tatwGadget.clockPanel.shrinkIfIdle = 1;
    }
    tatwGadget.clockPanel.shrinkIfIdle =
        tatwGadget.clockPanel.shrinkIfIdle == 1;
    if (view.resizable == 'false') {
      tatwGadget.onMouseOver();
      tatwGadget.onMouseOut();
    }
  } else if (event.propertyName == OPTION_NAMES.SHRINK_TIME) {
    if (isNaN(parseInt(tatwGadget.clockPanel.shrinkTime =
        options.getValue(OPTION_NAMES.SHRINK_TIME)))) {
      options.putValue(OPTION_NAMES.SHRINK_TIME, 10);
      tatwGadget.clockPanel.shrinkTime = 10;
    }
    if (view.resizable == 'false') {
      tatwGadget.onMouseOut();
    }
  } else if (event.propertyName == OPTION_NAMES.SHRINK_PERCENT) {
    if (isNaN(parseInt(tatwGadget.clockPanel.shrinkPercent =
        options.getValue(OPTION_NAMES.SHRINK_PERCENT)))) {
      options.putValue(OPTION_NAMES.SHRINK_PERCENT, 50);
      tatwGadget.clockPanel.shrinkPercent = 50;
    }
    if (view.resizable == 'false') {
      tatwGadget.onMouseOut();
    }
  }
};

/**
 * Called when the gadget is undocked
 * enables the shrink if idle option if selected
 */
TatwGadget.prototype.onUnDock = function() {
  view.resizable = 'false';
  view.onmouseover = 'tatwGadget.onMouseOver()';
  view.onmouseout = 'tatwGadget.onMouseOut()';
  this.onMouseOut();
};

/**
 * Called when the gadget is docked
 * disables the shrink if idle option
 */
TatwGadget.prototype.onDock = function() {
  view.resizable = 'zoom';
  view.onmouseover = '';
  view.onmouseout = '';
  if (this.clockPanel.zoomTimer) {
    clearInterval(this.clockPanel.zoomTimer);
  }
  if (this.shrinkTimer) {
    clearInterval(this.shrinkTimer);
  }
  this.clockPanel.zoomTimer=null;
  this.clockPanel.zoom(100);
};

/**
 * Called when the mouse hovers over the gadget
 * if the shrink if idle option is selected, the gadget returns to full size
 */
TatwGadget.prototype.onMouseOver = function() {
  if (this.shrinkTimer) {
    clearInterval(this.shrinkTimer);
  }
  if (this.clockPanel.zoomTimer) {
    clearInterval(this.clockPanel.zoomTimer);
    this.clockPanel.animateZoom(this.clockPanel.curentZoom, 100, 10, 10);
    return;
  }
  if (view.resizable != 'false') {
    this.clockPanel.animateZoom(this.clockPanel.curentZoom, 100, 10, 10);
    return;
  }
  if (this.clockPanel.curentZoom != 100) {
    this.shrinkTimer = setTimeout(
        function() {
          tatwGadget.clockPanel.animateZoom(tatwGadget.clockPanel.curentZoom,
                                            100, 10, 10);
        }, 500);
  }
};

/**
 * Called when the mouse leaves the gadget area
 * if the shrink if idle option is selected, a timer is set
 * to shrink the plugin after the idle time
 */
TatwGadget.prototype.onMouseOut = function() {
  if (this.shrinkTimer) {
    clearInterval(this.shrinkTimer);
  }
  if (!this.clockPanel.shrinkIfIdle || view.resizable != 'false') {
    return;
  }
  this.shrinkTimer = setTimeout(
      function() {
        tatwGadget.clockPanel.animateZoom(tatwGadget.clockPanel.curentZoom,
                                          tatwGadget.clockPanel.shrinkPercent,
                                          -3, 30);
      }, this.clockPanel.shrinkTime * 1000);
};
